/**
 * com.chaeron.GPS - An API for access to GPS devices.
 *
 *
 * Copyright (c) 2001, 2002 Chaeron Corporation,
 * All rights reserved.
 * 
 * Chaeron grants you a non-exclusive license to use, modify and re-distribute
 * this program under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version, provided that this copyright notice and 
 * license appear on all copies of the software.
 * 
 * Software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR
 * IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
 * HEREBY EXCLUDED. THE ENTIRE RISK ARISING OUT OF USING THE SOFTWARE IS ASSUMED
 * BY THE LICENSEE. See the GNU General Public License for more details.
 *
 * CHAERON AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
 * LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR DISTRIBUTING SOFTWARE.
 * IN NO EVENT WILL CHAERON OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
 * PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL
 * OR PUNITIVE DAMAGES, HOWEVER CAUSED AN REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF CHAERON HAS
 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * @version     1.02
 * @author  	Andrzej Jan Taramina, Chaeron Corporation
 *  			andrzej@chaeron.com
 */

package com.chaeron.platform.common;


/**
 * Vm contains various system level methods.
 * <p>
 * This class contains methods to copy arrays, obtain a timestamp,
 * sleep and get platform and version information.
 */

// NOTE:
// In the future, these methods may include getting unique object id's,
// getting object classes, sleep (for single threaded apps),
// getting amount of memory used/free, etc.
// The reason these methods should appear in this class and not somewhere
// like the Object class is because each method added to the Object class
// adds one more method to every object in the system.

public class Vm
{
	private Vm()
	{
	}
	
	/**
	 * Copies the elements of one array to another array. This method returns
	 * true if the copy is successful. It will return false if the array types
	 * are not compatible or if either array is null. If the length parameter
	 * would cause the copy to read or write past the end of one of the arrays,
	 * an index out of range error will occur. If false is returned then no
	 * copying has been performed.
	 * @param srcArray the array to copy elements from
	 * @param srcStart the starting position in the source array
	 * @param dstArray the array to copy elements to
	 * @param dstStart the starting position in the destination array
	 * @param length the number of elements to copy
	 */
	
	public static boolean copyArray(Object srcArray, int srcStart,
		Object dstArray, int dstStart, int length)
	{
		if (length < 0)
			return false;
		try
		{
			System.arraycopy(srcArray, srcStart, dstArray, dstStart, length);
		}
		catch (Exception e)
		{
			return false;
		}
		return true;
	}
	
	
	/**
	 * Returns true if the system supports a color display and false otherwise.
	 */
	
	public static boolean isColor()
	{
		return true;
	}
	
	/**
	 * Returns a time stamp in milliseconds. The time stamp is the time
	 * in milliseconds since some arbitrary starting time fixed when
	 * the VM starts executing. The maximum time stamp value is (1 << 30) and
	 * when it is reached, the timer will reset to 0 and will continue counting
	 * from there.
	 */
	
	public static int getTimeStamp()
	{
		return (int)(System.currentTimeMillis() % (1 << 30));
	}
	
	
	/** Returns the platform the Virtual Machine is running under as a string. */
	
	public static String getPlatform()
	{
		return "Windows";
	}
	
	/** 
	 * Returns the username of the user running the Virutal Machine. Because of
	 * Java's security model, this method will return null when called in a Java
	 * applet. This method will also return null under most WinCE devices (that
	 * will be fixed in a future release).
	 */
	
	public static String getUserName()
	{
		return null;
	}
	
	/**
	 * Returns the version of the Waba Virtual Machine. The major version is
	 * base 100. For example, version 1.0 has value 100. Version 2.0 has a
	 * version value of 200. A beta 0.8 VM will have version 80.
	 */
	public static int getVersion()
	{
		return 100;
	}
	
	/**
	 * Executes a command.
	 * <p>
	 * As an example, the following call could be used to run the command
	 * "scandir /p mydir" under Java, Win32 or WinCE:
	 * <pre>
	 * int result = Vm.exec("scandir", "/p mydir", 0, true);
	 * </pre>
	 * This example executes the Scribble program under PalmOS:
	 * <pre>
	 * Vm.exec("Scribble", null, 0, false);
	 * </pre>
	 * This example executes the web clipper program under PalmOS, telling
	 * it to display a web page by using launchCode 54 (CmdGoToURL).
	 * <pre>
	 * Vm.exec("Clipper", "http://www.yahoo.com", 54, true);
	 * </pre>
	 * The args parameter passed to this method is the arguments string
	 * to pass to the program being executed.
	 * <p>
	 * The launchCode parameter is only used under PalmOS. Under PalmOS, it is
	 * the launch code value to use when the Vm calls SysUIAppSwitch().
	 * If 0 is passed, the default launch code (CmdNormalLaunch) is used to
	 * execute the program.
	 * <p>
	 * The wait parameter passed to this method determines whether to execute
	 * the command asynchronously. If false, then the method will return without
	 * waiting for the command to complete execution. If true, the method will
	 * wait for the program to finish executing and the return value of the
	 * method will be the value returned from the application under Java, Win32
	 * and WinCE.
	 * <p>
	 * Under PalmOS, the wait parameter is ignored since executing another
	 * program terminates the running program.
	 *
	 * @param command the command to execute
	 * @param args command arguments
	 * @param launchCode launch code for PalmOS applications
	 * @param wait whether to wait for the command to complete execution before returning
	 */
	
	public static int exec(String command, String args, int launchCode, boolean wait)
	{
		java.lang.Runtime runtime = java.lang.Runtime.getRuntime();
		int status = -1;
		try	{
			java.lang.Process p = runtime.exec(command + " " + args);
			if (wait)
				status = p.waitFor();
			else
				status = 0;
		}
		catch (Exception e) {}
		return status;
	}
	
	/**
	 * Sets the device's "auto-off" time. This is the time in seconds where, if no
	 * user interaction occurs with the device, it turns off. To keep the device always
	 * on, pass 0. This method only works under PalmOS. The integer returned is
	 * the previous auto-off time in seconds.
	 */
	
	public static int setDeviceAutoOff(int seconds)
	{
		return 0;
	}
	
	/**
	 * Causes the VM to pause execution for the given number of milliseconds.
	 * @param millis time to sleep in milliseconds
	 */
	
	public static void sleep(int millis)
	{
		try
		{
			Thread.currentThread().sleep(millis);
		}
		catch (Exception e) {}
	}
	
	
	/**
	 * Causes the VM to set the background of the main window to white
	 *
	 * @param white set background to white if true
	 */
	
	public static void setBackgroundWhite( boolean white )
	{
		// Do nothing
	}
	
	
	/**
	 * Debug function
	 *<br>
	 * Writes a string to the upper left courner of the screen for 1/2 second
	 *
	 * @param sDebug String to write. 160 pixels maximum length
	 */
	public static void debug (String sDebug) 
	{
		debug (sDebug, 75); // 750 ms
	}
	
	/**
	 * Debug function
	 *<br>
	 * Writes a string to the upper left courner of the screen for 1/2 second
	 *
	 * @param sDebug String to write. 160 pixels maximum length
	 */
	public static void debug (String sDebug, int waitTime) 
	{
		System.out.println( sDebug );
	}
}